/**
 * 
 */
package speculoos.valid;

import java.util.Map;
import java.util.regex.Pattern;

/**
 * A validator for checking matching of input attributes against a regular
 * expression. This validator checks that a given property in the input object
 * matches a regular expression. This implies that the property is a string. If
 * the property value is null (ie. does not exists or is undefined) then the
 * behavior is controlled by attribute <code>validateNull</code>:
 * <ul>
 * <li>if set, then it returns true,</li>
 * <li>if unset, then it returns false.</li>
 * </ul>
 * 
 * @author nono
 * @version $Id$
 */
public class RegexValidator extends AtomicValidator {

	private boolean ignoreNull;

	private String property;

	private Pattern pattern;
	/**
	 * @return Returns the property.
	 */
	public String getProperty() {
		return property;
	}

	/**
	 * Sets the property to validate.
	 * 
	 * @param name
	 *            name of a property
	 */
	public void setProperty(String name) {
		this.property = name;
	}

	/**
	 * Sets the pattern of the property. This is a regular expression following
	 * {@link Pattern} syntax.
	 * 
	 * @param pat
	 *            a regular expression for valiidating input.
	 */
	public void setPattern(String pat) {
		this.pattern = Pattern.compile(pat);
	}

	/*
	 *  (non-Javadoc)
	 * @see speculoos.core.Mapper#map(java.lang.Object, java.util.Map)
	 */
	public Object map(Object input, Map env) throws InvalidateException {
		Object v = getTypeHelper().get(input, property);
		if (v == null)
			if (ignoreNull)
				return input;
			else
				throw new InvalidateException(getName()
						+ ": null value not allowed");
		String val = v.toString();
		if (pattern.matcher(val).matches())
			return input;
		else
			throw new InvalidateException(getName() + ": " + val
					+ " does not match " + pattern);
	}

	/**
	 * @return Returns the ignoreNull.
	 */
	public boolean isIgnoreNull() {
		return ignoreNull;
	}

	/**
	 * @param ignoreNull
	 *            The ignoreNull to set.
	 */
	public void setIgnoreNull(boolean ignoreNull) {
		this.ignoreNull = ignoreNull;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return property + " ~= " + pattern;
	}

	public String getName() {
		return "RegexValidator";
	}

}
